package com.hanlei.test;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.junit.Test;

import java.io.*;
import java.util.List;
import java.util.zip.ZipInputStream;

public class ActivitiDemo {
    @Test
    public void test(){
        //1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.使用service进行流程部署。定义一个流程名称,把Bpmn和png部署到数据中
        Deployment deploy = repositoryService.createDeployment()
                .name("出差申请流程")
                .addClasspathResource("bpmn/evection.bpmn")
                .addClasspathResource("bpmn/evection.png")
                .deploy();
        //4.输出部署信息
        System.out.println("流程部署id="+deploy.getId());
        System.out.println("流程部署名称="+deploy.getName());
    }

    /**
     * 启动流程实例
     * act_hi_actinst       流程实例执行的历史
     * act_hi_identitylink      流程参与者的历史信息
     * act_hi_procinst      流程实例的历史信息
     * act_hi_taskinst      任务执行的历史
     * act_ru_execution     流程的执行者信息
     * act_ru_identitylink      流程参与者信息
     * act_ru_task      任务信息
     */
    @Test
    public void testStartProcess(){
        //1.创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取RuntimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //根据流程定义的id启动流程
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myProcess_1");
        //输出内容
        System.out.println("流程定义ID："+instance.getProcessDefinitionId());
        System.out.println("流程实例ID："+instance.getId());
        System.out.println("当前活动的ID"+instance.getActivityId());
    }

    /**
     * 查询个人待执行的任务
     */
    @Test
    public void testFindPersonalTaskList(){
        //1.获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.taskService
        TaskService taskService = processEngine.getTaskService();
        //3.根据流程key 和 任务负责人 查询任务
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("zhangsan")
                .list();
        //4.输出
        for (Task task: taskList) {
            System.out.println("流程实例id="+task.getProcessInstanceId());
            System.out.println("任务id="+task.getId());
            System.out.println("任务负责人="+task.getAssignee());
            System.out.println("任务名称="+task.getName());
        }
    }

    /**
     * 完成个人任务
     */
    @Test
    public void completTask(){
      //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        //完成任务 参数：任务ID ,完成张三的任务
        //taskService.complete("5005");
        //获取jerry-myEvection 对应的任务
        //完成jerry
        /*Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("jerry")
                .singleResult();
        taskService.complete(task.getId());*/
        //完成tack
        /*Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("tack")
                .singleResult();
        taskService.complete(task.getId());*/

        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("rose")
                .singleResult();
        taskService.complete(task.getId());
    }


    /**
     * 使用zip包进行批量部署
     */
    @Test
    public void deployProcessByZip(){
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //流程部署
        //读取资源包 构成inputStream
        InputStream inputStream = this.getClass()
                .getClassLoader()
                .getResourceAsStream("bpmn/evection.zip");
        //用InputStream构成ZipInputStream
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        Deployment deploy = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)
                .deploy();

        System.out.println("流程部署ID"+deploy.getId());
        System.out.println("流程部署名称"+deploy.getName());
    }

    /**
     * 查询流程定义
     */
    @Test
    public void queryProcessDefinition(){
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //获取ProcessDefinitionQuery
        ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();

        //查询当前所有的流程
        List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey("myProcess_1")
                .orderByProcessDefinitionVersion()
                .desc()
                .list();
        //输出信息
        for (ProcessDefinition processDefinition:
                definitionList) {
            System.out.println("流程定义ID"+processDefinition.getId());
            System.out.println("流程定义名称"+processDefinition.getName());
            System.out.println("流程定义KEY"+processDefinition.getKey());
            System.out.println("流程定义版本"+processDefinition.getVersion());
            System.out.println("流程部署ID"+processDefinition.getDeploymentId());
        }
    }

    /**
     * 删除流程部署信息
     *
     * 流程未走完的情况下 使用级联删除
     */
    @Test
    public void deleteDeployMent(){
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过引擎获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //repositoryService.deleteDeployment("1");

        //级联删除  true 级联删除 false 不级联删除
        repositoryService.deleteDeployment("1",true);

    }

    /**
     * 下载 资源文件
     * 方案一：使用activiti提供的API,来下载资源文件
     * 方案二： 自己写代码从数据库中下载文件,使用JDBC对BLOB类型,CLOB数据类型读取出来，保存到文件目录
     * 解决IO操作：commons.jar
     */

    @Test
    public void getDeployment() throws IOException {
        //获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //通过引擎获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.获取查询对象ProcessDefinitionQuery查询流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("myProcess_1")
                .singleResult();
        //4.通过流程定义信息,获取部署ID
        String deploymentId = processDefinition.getDeploymentId();
        //通过流程定义信息,获取png的目录和名称
        String pngName = processDefinition.getDiagramResourceName();
        //5.1通过ID和png名称获取图片资源
        InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
        //5.2获取bpmn的流
        String bpmnName = processDefinition.getResourceName();
        InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
        //6.OutputStream
        File pngFile = new File("D://activiti1.png");
        File bpmnFile = new File("D://activiti1.bpmn");
        FileOutputStream pngOutStream = new FileOutputStream(pngFile);
        FileOutputStream bpmnOutStream= new FileOutputStream(bpmnFile);
        //7.输入流 输出流的转换
        IOUtils.copy(pngInput,pngOutStream);
        IOUtils.copy(bpmnInput,bpmnOutStream);
        //8.g关闭流
        pngOutStream.close();
        bpmnOutStream.close();
        pngInput.close();
        bpmnInput.close();
    }

}
